#include "stdafx.h"
#include "Hud.h"

namespace MyGame {

Hud::Hud(Game* game) : DrawableGameComponent(game) {
    this->enemyController = NULL;
}

Hud::~Hud(void) {
}

EnemyController*Hud::GetEnemyController() const {
    return this->enemyController;
}

void Hud::SetEnemyController(EnemyController* val) {
    this->enemyController = val;
}

void Hud::Draw(FLOAT timeDelta) {
    if (this->info->GetVisible()) {
        this->info->Draw(timeDelta);
    }

    this->lblHealth->Draw(timeDelta);
    this->lblMissiles->Draw(timeDelta);
    this->lblScore->Draw(timeDelta);

    this->GetGame()->GetGraphicsDevice()->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
    this->line->Begin();

    D3DXMATRIX viewProjection = this->GetGame()->GetCamera()->GetViewMatrix() * this->GetGame()->GetCamera()->GetProjectionMatrix();
    D3DXVECTOR3 crosshairPos = this->enemyController->GetPlayer()->GetPosition();
    crosshairPos.z += 50;
    D3DXMATRIX identity;
    D3DXMatrixIdentity(&identity);
    this->GetGame()->GetCamera()->Project(&crosshairPos, &crosshairPos, &identity);
    D3DXVECTOR2 crosshair[4];
    crosshair[0] = D3DXVECTOR2(crosshairPos.x - 10, crosshairPos.y);
    crosshair[1] = D3DXVECTOR2(crosshairPos.x + 10, crosshairPos.y);
    crosshair[2] = D3DXVECTOR2(crosshairPos.x, crosshairPos.y - 10);
    crosshair[3] = D3DXVECTOR2(crosshairPos.x, crosshairPos.y + 10);
    this->line->Draw(&crosshair[0], 2, d3d::WHITE);
    this->line->Draw(&crosshair[2], 2, d3d::WHITE);

    list<Enemy*>* enemies = this->enemyController->GetEnemies();
    for (list<Enemy*>::const_iterator it = enemies->begin(); it != enemies->end(); ++it) {
        Enemy* enemy = *it;
        if (!enemy->GetTargeted() || enemy->GetState() != FLYINGSTATE_ALIVE) {
            continue;
        }

        d3d::BoundingBox* bb = enemy->GetBoundingBox();
        FLOAT midZ = ((bb->_max.z - bb->_min.z) / 2) + bb->_min.z;
        FLOAT difY = ((bb->_max.x - bb->_min.x) - (bb->_max.y - bb->_min.y)) / 2;
        FLOAT minY = bb->_min.y - difY;
        FLOAT maxY = bb->_max.y + difY;
        D3DXVECTOR3 boxCoords[5];
        boxCoords[0] = D3DXVECTOR3(bb->_min.x, minY, midZ);
        boxCoords[1] = D3DXVECTOR3(bb->_min.x, maxY, midZ);
        boxCoords[2] = D3DXVECTOR3(bb->_max.x, maxY, midZ);
        boxCoords[3] = D3DXVECTOR3(bb->_max.x, minY, midZ);
        boxCoords[4] = D3DXVECTOR3(bb->_min.x, minY, midZ);
        D3DCOLOR color = enemy->GetIncomigMissile() != NULL ? d3d::GREEN : d3d::WHITE;
        this->line->DrawTransform(&boxCoords[0], 5, &viewProjection, color);
    }

    this->line->End();
    this->GetGame()->GetGraphicsDevice()->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
}

void Hud::Initialize() {
    D3DVIEWPORT9 viewPort;
    this->GetGame()->GetGraphicsDevice()->GetViewport(&viewPort);

    this->info = new Label(this->GetGame());
    this->info->bounds.bottom = (viewPort.Height / 2);
    this->info->bounds.left = (viewPort.Width / 2) - 200;
    this->info->bounds.right = (viewPort.Width / 2) + 200;
    this->info->bounds.top = (viewPort.Height / 2) - 80;
    this->info->SetFormat(DT_CENTER);
    this->info->Initialize();

    this->lblHealth = new Label(this->GetGame());
    this->lblHealth->bounds.bottom = viewPort.Height;
    this->lblHealth->bounds.left = 0;
    this->lblHealth->bounds.right = 100;
    this->lblHealth->bounds.top = viewPort.Height - 20;
    this->lblHealth->Initialize();

    this->lblMissiles = new Label(this->GetGame());
    this->lblMissiles->bounds.bottom = viewPort.Height;
    this->lblMissiles->bounds.left = viewPort.Width - 100;
    this->lblMissiles->bounds.right = viewPort.Width;
    this->lblMissiles->bounds.top = viewPort.Height - 20;
    this->lblMissiles->Initialize();

    this->lblScore = new Label(this->GetGame());
    this->lblScore->bounds.bottom = viewPort.Height;
    this->lblScore->bounds.left = (viewPort.Width - 150) / 2;
    this->lblScore->bounds.right = (viewPort.Width - 150) / 2 + 150;
    this->lblScore->bounds.top = viewPort.Height - 20;
    this->lblScore->Initialize();
}

void Hud::LoadContent() {
    D3DXCreateLine(this->GetGame()->GetGraphicsDevice(), &this->line);
    this->line->SetAntialias(TRUE);
    this->line->SetWidth(2);

    this->info->LoadContent();
    this->lblHealth->LoadContent();
    this->lblMissiles->LoadContent();
    this->lblScore->LoadContent();
}

void Hud::Update(FLOAT timeDelta) {
    Player* player = this->enemyController->GetPlayer();
    char buf[50];

    _snprintf_s(buf, 50, "HP: %d", player->GetHealth());
    this->lblHealth->SetText(string(buf));
    _snprintf_s(buf, 50, "AAM: %d", player->GetMissiles());
    this->lblMissiles->SetText(string(buf));
    _snprintf_s(buf, 50, "Score: %d", player->GetScore());
    this->lblScore->SetText(string(buf));

    if (!player->GetEnabled()) {
        this->info->SetVisible(true);
        if (player->GetState() == FLYINGSTATE_ALIVE) {
            this->info->SetText("SOMEBODY SET UP US THE BOMB\nPRESS 'C' TO TAKE OFF");
        } else {
            this->info->SetText("GAME OVER\nPRESS 'ESC' TO QUIT");
        }
    } else {
        this->info->SetVisible(false);
    }
}

}
